﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Ddavidlib.GameEngine
{
    interface IConnectToLogSystem
    {
        void ConnectLogSystem(LogSystem gameLogSystem);
        void Log(string log);
    }

    public abstract class LogGameComponent : Microsoft.Xna.Framework.GameComponent, IConnectToLogSystem
    {
        string componentName;
        LogSystem logSystem;

        public LogGameComponent(Game game, string name)
            : base(game)
        {
            componentName = name;
            logSystem = null;
        }

        public LogGameComponent(Game game, string name, LogSystem usedLogSystem)
            : base(game)
        {
            componentName = name;
            logSystem = usedLogSystem;
        }

        public void ConnectLogSystem(LogSystem gameLogSystem)
        {
            logSystem = gameLogSystem;
        }

        public void Log(string log)
        {
            if (logSystem != null)
            {
                logSystem.AddLog(componentName + ": " + log);
            }
        }
    }

    public class LogSystem : Microsoft.Xna.Framework.DrawableGameComponent
    {
        ContentManager content;
        SpriteBatch spriteBatch;
        SpriteFont fontChinese;

        Rectangle logBlock;
        List<string> logStringList;

        public LogSystem(Game game)
            : base(game)
        {
            // TODO: Construct any child components here
            content = new ContentManager(this.Game.Services, this.Game.Content.RootDirectory);
            logBlock = new Rectangle(0, 0, 600, 480);
            logStringList = new List<string>();
            Visible = false;
        }

        public LogSystem(Game game, Rectangle block)
            : base(game)
        {
            // TODO: Construct any child components here
            content = new ContentManager(this.Game.Services, this.Game.Content.RootDirectory);
            logBlock = block;
            logStringList = new List<string>();
            Visible = false;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here
            logStringList.Add("LogSystem: 記錄開始");

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            fontChinese = content.Load<SpriteFont>("SpriteFontChinese");

            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            content.Unload();

            base.UnloadContent();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here

            base.Update(gameTime);
        }

        protected override void OnEnabledChanged(object sender, EventArgs args)
        {
            if (Enabled)
            {
                logStringList.Add("LogSystem: 記錄開始");
            }
            else
            {
                logStringList.Add("LogSystem: 記錄結束");
            }

            base.OnEnabledChanged(sender, args);
        }

        public override void Draw(GameTime gameTime)
        {
            Vector2 textPosition = new Vector2(logBlock.X, logBlock.Y);

            spriteBatch.Begin();

            foreach (string logString in logStringList)
            {
                spriteBatch.DrawString(fontChinese, logString, textPosition, Color.White);
                textPosition.Y += 20.0f;
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }

        public void AddLog(string log)
        {
            logStringList.Add(log);
            if (logStringList.Count() > logBlock.Height / 20 - 1)
            {
                logStringList.RemoveAt(0);
            }
        }
    }
}
